﻿// Пример перегрузки бинарных операторов (+) и (-)
// Добавлено выполение операций над встроенными C#-типами 
// Добавлена перегрузка операторов сравнения (>) и (<)
// Добавлена перегрузка логических операторов (!), (|), (&)
// Добавлены операторы преобразования

using System;

class OverloadOperatorsDemo
{
    public static void Main()
    {
        ThreeDBin t1 = new ThreeDBin(1, -26, 21);
        ThreeDBin t2 = new ThreeDBin(-34, -11, 13);
        ThreeDBin t3 = new ThreeDBin();

        t1.Show();
        t2.Show();

        t3 = t1 - t2;
        Console.WriteLine("Разность координат:");
        t3.Show();

        t3 = t1 + t2;
        Console.WriteLine("Сумма координат:");
        t3.Show();

        Console.WriteLine("Смещение координакт");
        t3 += 10;
        t3.Show();

        Console.WriteLine("Проверка оператора (>)");
        if (t1 > t2)
            Console.WriteLine("t1 > t2");

        Console.WriteLine("Неявное преобразование t1 в int");
        //Console.WriteLine("t1 * 1 = {0}", 1 * t1);
        Console.WriteLine("Явное преобразование оператора t2");
        Console.WriteLine((int)t2);

        Console.ReadLine();
    }
}

// Класс трехмерной координаты
class ThreeDBin
{
    int x;
    int y;
    int z;

    public ThreeDBin()
    {
        x = y = z = 0;
    }

    public ThreeDBin(int xc, int yc, int zc)
    {
        x = xc;
        y = yc;
        z = zc;
    }

    public void Show()
    {
        Console.WriteLine("X: {0}, Y: {1}, Z: {2}", x, y, z);
    }

    // Перегрузка оператора +
    public static ThreeDBin operator + (ThreeDBin t1, ThreeDBin t2)
    {
        ThreeDBin t = new ThreeDBin();
        
        t.x = t1.x + t2.x;
        t.y = t1.y + t2.y;
        t.z = t1.z + t2.z;

        return t;
    }

    // Перегрузка оператора -
    public static ThreeDBin operator -(ThreeDBin t1, ThreeDBin t2)
    {
        ThreeDBin t = new ThreeDBin();

        t.x = t1.x - t2.x;
        t.y = t1.y - t2.y;
        t.z = t1.z - t2.z;

        return t;
    }

    // Смещение осей на определенную величну
    // Добавление к классу int значения
    // Очередная перегрузка оператора (+)
    public static ThreeDBin operator +(ThreeDBin t1, int num)
    {
        ThreeDBin t = new ThreeDBin();

        t.x = t1.x + num;
        t.y = t1.y + num;
        t.z = t1.z + num;

        return t;
    }

    // Перегрузка операторов (>) и (<)
    public static bool operator >(ThreeDBin t1, ThreeDBin t2)
    {
        if ((t1.x > t2.x) && (t1.y > t2.y) && (t1.z > t2.z))
            return true;
        else return false;
    }
    public static bool operator <(ThreeDBin t1, ThreeDBin t2)
    {
        if ((t1.x < t2.x) && (t1.y < t2.y) && (t1.z < t2.z))
            return true;
        else return false;
    }

    // Перегрузка оператора НЕ (!)
    // Унарный оператор
    public static bool operator ! (ThreeDBin t1)
    {
        if ((t1.x == 0) && (t1.y == 0) || (t1.z == 0))
            return true;
        else return false;
    }

    // Перегрузка оператора И (&)
    // Если одна из координат содержит 0, возвращает false

    public static bool operator &(ThreeDBin t1, ThreeDBin t2)
    {
        if (((t1.x != 0) && (t1.y != 0) && (t1.z != 0))
            & ((t2.x != 0) && (t2.y != 0) && (t2.z != 0)))
            return true;
        else return false;
    }

    // Перегрузка оператора ИЛИ (|)
    // Если все координаты содержат 0, возвращает false
    public static bool operator |(ThreeDBin t1, ThreeDBin t2)
    {
        if (((t1.x != 0) || (t1.y != 0) || (t1.z != 0))
            | ((t2.x != 0) || (t2.y != 0) || (t2.z != 0)))
            return true;
        else return false;
    }

    // Неявная перегрузка оператора преобразования в int.
    /*public static implicit operator int(ThreeDBin t1)
    {
        return t1.x * t1.y * t1.z;
    }*/

    // Явная перегрузка оператора преобразования в int
    public static explicit operator int(ThreeDBin t1)
    {
        return t1.x * t1.y * t1.z;
    }


}